import ast
import os
import json
import re
from django.utils import timezone
from zeep import Client
from django import forms
from django.contrib.auth.decorators import permission_required, login_required
from django.contrib.auth.hashers import check_password
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.views import View
from django.views.generic import DetailView
from django.shortcuts import redirect
from django.core.exceptions import ValidationError

from public.viewFunc.ansibleIndex import AnsibleOpt
from django.contrib.auth.models import User, Permission
import redis
from onecup.settings import BASE_DIR, REDIS_ADDR, REDIS_PORT, REDIS_PD, result_db, ansible_result_redis_db, MONITOR_URL, DES_SECRET_KEY
from public.resources import *
from tablib import Dataset
from public.filters import *
from django.contrib.auth import login, update_session_auth_hash
from collections import defaultdict
from public.viewFunc.util import des_decrypt, des_encrypt


class Index(View):

    def get(self, request, *k, **kw):
        data = {}
        return redirect('/account/login')


def pwd_validate(value):
    name_re = re.compile(r'^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*()])[0-9a-zA-Z!@#$%^&*()]{4,}$')
    if not name_re.match(value):
        raise ValidationError('密码长度最少6位，必须包含数字、大小写字母、特殊字符')


class HostForm(forms.Form):
    systemname = forms.CharField(required=True, label='系统', error_messages={"required": "系统不能为空"})
    hostname = forms.CharField(required=True, label='服务器', error_messages={'required': u'服务器不能为空'})
    ip = forms.CharField(required=True, label='ip', error_messages={'required': u'ip不能为空'})


class SystemForm(forms.Form):
    systemname = forms.CharField(required=True, label='系统', error_messages={"required": "系统不能为空"})
    remark = forms.CharField(required=True, label='描述', error_messages={'required': u'描述不能为空'})
    control_host = forms.CharField(required=True, label='控制主机ip', error_messages={'required': u'控制主机ip不能为空'})
    task = forms.CharField(required=True, label='任务', error_messages={'required': u'任务不能为空'})
    agent_user = forms.CharField(required=True, label='agent用户', error_messages={'required': u'agent用户不能为空'})
    agent_pass = forms.CharField(required=True, label='agent密码', error_messages={'required': u'agent密码不能为空'})
    ssh_user = forms.CharField(required=True, label='ssh用户', error_messages={'required': u'ssh用户不能为空'})
    ssh_pass = forms.CharField(required=True, label='ssh密码', error_messages={'required': u'ssh密码不能为空'})


class ApplicationForm(forms.Form):
    module = forms.CharField(required=True, label='系统', error_messages={"required": "模块不能为空"})


class PlaybookForm(forms.Form):
    playbook = forms.CharField(required=True, label='名称', error_messages={"required": "名称不能为空"})
    nickName = forms.CharField(required=True, label='别名', error_messages={'required': u'别名不能为空'})
    remark = forms.CharField(required=True, label='描述', error_messages={'required': u'描述不能为空'})


class SoftwareForm(forms.Form):
    software = forms.CharField(required=True, label='名称', error_messages={"required": "名称不能为空"})
    remark = forms.CharField(required=True, label='描述', error_messages={'required': u'描述不能为空'})


class AnsibleRoleForm(forms.Form):
    ansiblerole = forms.CharField(required=True, label='名称', error_messages={"required": "名称不能为空"})
    remark = forms.CharField(required=True, label='描述', error_messages={'required': u'描述不能为空'})


class UserForm(forms.Form):
    username = forms.CharField(required=True, label='用户名', error_messages={"required": "用户名不能为空"})
    password = forms.CharField(required=True, label='密码', validators=[pwd_validate],
                               error_messages={'required': u'密码不能为空'})
    group = forms.CharField(required=True, label='所属组', error_messages={'required': u'所属组不能为空'})


class UserModForm(forms.Form):
    username = forms.CharField(required=True, label='用户名', error_messages={"required": "用户名不能为空"})
    status = forms.CharField(required=True, label='账号状态', error_messages={'required': u'账号状态不能为空'})
    group = forms.CharField(required=True, label='所属组', error_messages={'required': u'所属组不能为空'})


class PwdModForm(forms.Form):
    pwd_old = forms.CharField(required=True, label='原密码', error_messages={"required": "原密码不能为空"})
    pwd_new = forms.CharField(required=True, label='新密码', error_messages={'required': u'新密码不能为空'})
    pwd_new_confirm = forms.CharField(required=True, validators=[pwd_validate], label='新密码确认',
                                      error_messages={'required': u'新密码确认不能为空'})


class RoleForm(forms.Form):
    rolename = forms.CharField(required=True, label='角色名', error_messages={"required": "角色名不能为空"})


@permission_required('public.ansible_view', raise_exception=True)
def ansibletasklist(request):
    """ansible任务列表页"""
    playbook = AnsibleTaskFilter(request.GET, queryset=AnsibleTasks.objects.all())
    paginator = Paginator(playbook.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': playbook, }
    return render(request, 'public/ansibletasks_list.html', context)


@permission_required('public.asset_manage', raise_exception=True)
def assetslist(request):
    assetslist = AssetsFilter(request.GET, queryset=Assets.objects.all())
    paginator = Paginator(assetslist.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': assetslist}
    return render(request, 'public/assets_list.html', context)


class AnsibleTaskDetail(LoginRequiredMixin, DetailView):
    """Ansible Tasks 详情页"""
    login_url = '/account/login'
    redirect_field_name = 'redirect_to'
    model = AnsibleTasks
    context_object_name = 't'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        tid = context['t'].AnsibleID
        ar = context['t'].AnsibleResult
        cr = context['t'].CeleryResult
        # print("tid:%s, AnsibleResult:%s CeleryResult: %s" % (tid, ar, cr))
        if tid and (ar == '' or cr == ''):
            r = redis.Redis(host=REDIS_ADDR, password=REDIS_PD, port=REDIS_PORT, db=ansible_result_redis_db)
            a = redis.Redis(host=REDIS_ADDR, password=REDIS_PD, port=REDIS_PORT, db=result_db)
            rlist = r.lrange(tid, 0, -1)
            rlen = 0
            max_len = 1024*1024*8
            for i in range(len(rlist)):
                rlen += len(rlist[i])
                if rlen > max_len:
                    rlist = rlist[:i]
                    print("over the max len")
                    break
            try:
                at = AnsibleTasks.objects.filter(AnsibleID=tid)[0]
                tmpar = json.dumps([json.loads(i.decode()) for i in rlist])
                at.AnsibleResult = tmpar
                context['t'].AnsibleResult = tmpar
                ct = a.get('celery-task-meta-%s' % at.CeleryID).decode()
                context['t'].CeleryResult = ct
                at.CeleryResult = ct
                at.save()
            except:
                pass
        return context


@permission_required('public.ansible_view', raise_exception=True)
def analysisload(request):
    SystemName = request.POST.get('SystemName')
    ansibleid = request.POST.get('ansibleid')
    AnsibleResult = request.POST.get('AnsibleResult')
    cnt = 0
    pattern = re.compile(r'DBLOAD(.+?)ENDLOAD')
    sqlcnt = pattern.findall(str(AnsibleResult))
    for line in sqlcnt:
        resinfo = line.strip()
        tbname = resinfo.split()[0]
        if tbname == "hostres":
            try:
                resrow = resinfo[resinfo.find("[") + 1:resinfo.find("]")]
                hr = resrow.split(",")
                hostname = hr[0].strip()[1:-1]
                sship = hr[1].strip()[1:-1]
                ipaddrs = hr[2].strip()[1:-1]
                kl = hr[3].strip()[1:-1]
                osrelease = hr[4].strip()[1:-1]
                productname = hr[5].strip()[1:-1]
                processorname = hr[6].strip()[1:-1]
                cpunum = int(hr[7].strip()[1:-1])
                cpurate = float(hr[8].strip()[1:-1])
                memtotal = hr[9].strip()[1:-1]
                memrate = float(hr[10].strip()[1:-1])
                fileUsage = hr[11].strip()[1:-1]
                (hrs, _created) = HostRes.objects.get_or_create(systemname=SystemName, sship=sship)
                HostRes.objects.filter(id=hrs.id).update(ipaddrs=ipaddrs, hostname=hostname, kernel=kl, osrelease=osrelease,
                                                         productname=productname, processorname=processorname,
                                                         cpunum=cpunum, cpurate=cpurate, memtotal=memtotal,
                                                         memrate=memrate, fileUsage=fileUsage, AnsibleID=ansibleid)
                if hrs:
                    cnt += 1
            except ValueError as ve:
                print(ve)
            except Exception as er:
                print(er)

    return JsonResponse(cnt, safe=False)


@permission_required('public.system_manage', raise_exception=True)
def systemslist(request):
    """系统列表页"""
    systems = SystemFilter(request.GET, queryset=SystemsLists.objects.all())
    paginator = Paginator(systems.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': systems, }
    return render(request, 'public/systems.html', context)


@permission_required('public.system_manage', raise_exception=True)
def systeminfo(request):
    """系统信息列表页"""
    id = request.GET.get('id')
    system = SystemsLists.objects.get(id=id)
    return render(request, 'public/systeminfo.html', {'system': system})


@permission_required('public.system_manage', raise_exception=True)
def systemsadd(request):
    """系统新增页面"""
    obj = SystemForm()
    if request.method == 'POST':
        system_form = SystemForm(request.POST)
        if system_form.is_valid():
            systemname = request.POST.get('systemname')
            supersystem = request.POST.get('supersystem')
            network_system_type = request.POST.get('network_system_type')
            department = request.POST.get('department')
            remark = request.POST.get('remark')
            social_influence_value = request.POST.get('social_influence_value')
            social_influence_basis = request.POST.get('social_influence_basis')
            scale_service_scope_value = request.POST.get('scale_service_scope_value')
            scale_service_scope_basis = request.POST.get('scale_service_scope_basis')
            service_important_value = request.POST.get('service_important_value')
            service_important_basis = request.POST.get('service_important_basis')
            security_level_value = request.POST.get('security_level_value')
            security_level = request.POST.get('security_level')
            control_host = request.POST.get('control_host')
            agent_user = request.POST.get('agent_user')
            agent_pass = request.POST.get('agent_pass')
            ssh_user = request.POST.get('ssh_user')
            ssh_pass = request.POST.get('ssh_pass')
            task = request.POST.get('task')
            systemname_indb = SystemsLists.objects.filter(systemname=systemname)
            if systemname_indb:
                msg = "系统名字已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                SystemsLists.objects.create(
                    systemname=systemname,
                    supersystem=supersystem,
                    network_system_type=network_system_type,
                    department=department,
                    social_influence_value=social_influence_value,
                    social_influence_basis=social_influence_basis,
                    scale_service_scope_value=scale_service_scope_value,
                    service_important_value=service_important_value,
                    service_important_basis=service_important_basis,
                    scale_service_scope_basis=scale_service_scope_basis,
                    security_level_value=security_level_value,
                    security_level=security_level,
                    remark=remark,
                    control_host=control_host,
                    agent_user=agent_user,
                    agent_pass=str(des_encrypt(DES_SECRET_KEY, agent_pass), 'utf-8'),
                    ssh_user=agent_user,
                    ssh_pass=str(des_encrypt(DES_SECRET_KEY, ssh_pass), 'utf-8'),
                    task=task
                )
                return redirect('/ansible/systemslist')
        else:
            errors = system_form.errors
            return render(request, 'public/systemsadd.html', {'obj': system_form, 'error': errors})
    return render(request, 'public/systemsadd.html', {"obj": obj})


@permission_required('public.system_manage', raise_exception=True)
def systemsmod(request):
    """系统修改页面"""
    id = request.GET.get('id')
    systems = SystemsLists.objects.get(id=id)
    group = Group.objects.all()
    obj = SystemForm()
    if request.method == 'POST':
        system_form = SystemForm(request.POST)
        if system_form.is_valid():
            systemname = request.POST.get('systemname')
            supersystem = request.POST.get('supersystem')
            network_system_type = request.POST.get('network_system_type')
            department = request.POST.get('department')
            remark = request.POST.get('remark')
            social_influence_value = request.POST.get('social_influence_value')
            social_influence_basis = request.POST.get('social_influence_basis')
            scale_service_scope_value = request.POST.get('scale_service_scope_value')
            scale_service_scope_basis = request.POST.get('scale_service_scope_basis')
            service_important_value = request.POST.get('service_important_value')
            service_important_basis = request.POST.get('service_important_basis')
            security_level_value = request.POST.get('security_level_value')
            security_level = request.POST.get('security_level')
            control_host = request.POST.get('control_host')
            agent_user = request.POST.get('agent_user')
            agent_pass = request.POST.get('agent_pass')
            ssh_user = request.POST.get('ssh_user')
            ssh_pass = request.POST.get('ssh_pass')
            task = request.POST.get('task')
            if systemname == systems.systemname:
                systemname_indb = ''
            else:
                systemname_indb = SystemsLists.objects.filter(systemname=systemname)
            if systemname_indb:
                msg = "系统名字已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                SystemsLists.objects.filter(id=request.GET.get('id')).update(
                    systemname=systemname,
                    supersystem=supersystem,
                    network_system_type=network_system_type,
                    department=department,
                    social_influence_value=social_influence_value,
                    social_influence_basis=social_influence_basis,
                    scale_service_scope_value=scale_service_scope_value,
                    service_important_value=service_important_value,
                    service_important_basis=service_important_basis,
                    scale_service_scope_basis=scale_service_scope_basis,
                    security_level_value=security_level_value,
                    security_level=security_level,
                    remark=remark,
                    control_host=control_host,
                    agent_user=agent_user,
                    agent_pass=str(des_encrypt(DES_SECRET_KEY, agent_pass), 'utf-8'),
                    ssh_user=ssh_user,
                    ssh_pass=str(des_encrypt(DES_SECRET_KEY, ssh_pass), 'utf-8'),
                    task=task
                )
                return redirect('/ansible/systemslist')
        else:
            errors = system_form.errors
            return render(request, 'public/systemsmod.html', {'obj': system_form, 'systems': systems, 'error': errors})
    return render(request, 'public/systemsmod.html', {"obj": obj, 'systems': systems})


@permission_required('public.system_manage', raise_exception=True)
def systemsdelete(request):
    """系统删除"""
    SystemsLists.objects.filter(id=request.GET.get('id')).delete()
    return redirect('/ansible/systemslist')


@permission_required('public.host_view', raise_exception=True)
def applicationlist(request):
    """应用列表页"""
    application = ApplicationFilter(request.GET, queryset=Applications.objects.all())
    paginator = Paginator(application.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': application, }
    return render(request, 'public/application.html', context)


@permission_required('public.host_view', raise_exception=True)
def applicationinfo(request):
    """应用信息列表页"""
    id = request.GET.get('id')
    application = Applications.objects.get(id=id)
    return render(request, 'public/applicationinfo.html', {'application': application})


@permission_required('public.application_manage', raise_exception=True)
def applicationadd(request):
    """应用新增页面"""
    user = User.objects.get(username=request.user.username)
    group = user.groups.all().first()
    if user.username == 'root':
        system = SystemsLists.objects.all()
    else:
        system = group.systemslists_set.all()
    obj = ApplicationForm()
    if request.method == 'POST':
        application_form = ApplicationForm(request.POST)
        if application_form.is_valid():
            module = request.POST.get('module')
            remark = request.POST.get('remark')
            install_path = request.POST.get('install_path')
            log_path = request.POST.get('log_path')
            config_path = request.POST.get('config_path')
            modules_port = request.POST.get('modules_port')
            user_name = request.POST.get('user_name')
            redundancy_type = request.POST.get('redundancy_type')
            cluster_software = request.POST.get('cluster_software')
            storage = request.POST.get('storage')
            ip = request.POST.get('ip')
            ip = ip.replace(' ', '').replace('\r\n', '')
            if ip[-1] is ',':
                ip = ip[:-1].split(',')
            else:
                ip = ip.split(',')
            systemname = request.POST.get('systemname')
            applicationname_indb = Applications.objects.filter(module=module)
            if applicationname_indb:
                msg = "模块名字已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                for i in ip:
                    try:
                        host = HostsLists.objects.get(ip=i)
                    except:
                        msg = "ip %s 地址不存在,点击重新填写" % i
                        return render(request, 'public/fail.html', {'msg': msg})
                application = Applications.objects.create(
                    module=module,
                    remark=remark,
                    install_path=install_path,
                    config_path=config_path,
                    log_path=log_path,
                    modules_port=modules_port,
                    user_name=user_name,
                    redundancy_type=redundancy_type,
                    cluster_software=cluster_software,
                    storage=storage,
                )
                for i in ip:
                    host = HostsLists.objects.get(ip=i)
                    host.application.add(application.id)
                sys = SystemsLists.objects.get(systemname=systemname)
                sys.application.add(application.id)
                return redirect('/ansible/applicationlist')
        else:
            errors = application_form.errors
            return render(request, 'public/applicationadd.html',
                          {'obj': application_form, 'system': system, 'error': errors})
    return render(request, 'public/applicationadd.html', {"obj": obj, 'system': system})


@permission_required('public.application_manage', raise_exception=True)
def applicationmod(request):
    """应用修改页面"""
    id = request.GET.get('id')
    application = Applications.objects.get(id=id)
    ips = application.hostslists_set.all()
    sys = application.systemslists_set.all().first()
    obj = ApplicationForm()
    if request.method == 'POST':
        application_form = ApplicationForm(request.POST)
        if application_form.is_valid():
            module = request.POST.get('module')
            remark = request.POST.get('remark')
            install_path = request.POST.get('install_path')
            log_path = request.POST.get('log_path')
            config_path = request.POST.get('config_path')
            modules_port = request.POST.get('modules_port')
            user_name = request.POST.get('user_name')
            redundancy_type = request.POST.get('redundancy_type')
            cluster_software = request.POST.get('cluster_software')
            storage = request.POST.get('storage')
            ip = request.POST.get('ip')
            if module == application.module:
                applicationname_indb = ''
            else:
                applicationname_indb = Applications.objects.filter(module=module)
            if applicationname_indb:
                msg = "模块名字已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                ip = ip.replace(' ', '').replace('\r\n', '')
                if ip[-1] is ',':
                    ip = ip[:-1].split(',')
                else:
                    ip = ip.split(',')
                if application.hostslists_set.all().exists():
                    hosts = application.hostslists_set.all()
                    for i in hosts:
                        host = HostsLists.objects.get(ip=i.ip)
                        host.application.remove(application.id)
                    for i in ip:
                        try:
                            host = HostsLists.objects.get(ip=i)
                        except:
                            msg = "ip %s 地址不存在,点击重新填写" % i
                            return render(request, 'public/fail.html', {'msg': msg})
                        host.application.add(application.id)
                else:
                    for i in ip:
                        try:
                            host = HostsLists.objects.get(ip=i)
                        except:
                            msg = "ip %s 地址不存在,点击重新填写" % i
                            return render(request, 'public/fail.html', {'msg': msg})
                        host.application.add(application.id)
                Applications.objects.filter(id=request.GET.get('id')).update(
                    module=module,
                    remark=remark,
                    install_path=install_path,
                    config_path=config_path,
                    log_path=log_path,
                    modules_port=modules_port,
                    user_name=user_name,
                    redundancy_type=redundancy_type,
                    cluster_software=cluster_software,
                    storage=storage,
                )
                return redirect('/ansible/applicationlist')
        else:
            errors = application_form.errors
            return render(request, 'public/applicationmod.html',
                          {'obj': application_form, 'application': application, 'error': errors})
    return render(request, 'public/applicationmod.html',
                  {"obj": obj, 'application': application, 'ips': ips, 'sys': sys})


@permission_required('public.application_manage', raise_exception=True)
def applicationdelete(request):
    """系统删除"""
    Applications.objects.filter(id=request.GET.get('id')).delete()
    return redirect('/ansible/applicationlist')


@permission_required('public.host_view', raise_exception=True)
def hostslist(request):
    """主机列表页"""
    user = User.objects.get(username=request.user.username)
    if user.username == 'root':
        hosts = HostFilter(request.GET, request=request, queryset=HostsLists.objects.all())
    else:
        if user.groups.all().first():
            group = user.groups.all().first()
            system = group.systemslists_set.all()
            systems = list(system.values_list('systemname', flat=True))
            if systems:
                hosts = HostFilter(request.GET, request=request, queryset=HostsLists.objects.filter(systemname__in=systems))
            else:
                msg = 1
                return render(request, 'public/hosts.html', {'msg': msg})
    paginator = Paginator(hosts.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': hosts, }
    return render(request, 'public/hosts.html', context)


def hostsinfo(request):
    """资源使用统计页"""
    user = User.objects.get(username=request.user.username)
    if user.username == 'root':
        hosts = HostinfoFilter(request.GET, queryset=HostRes.objects.all())
    else:
        if user.groups.all().first():
            group = user.groups.all().first()
            system = group.systemslists_set.all()
            systems = list(system.values_list('systemname', flat=True))
            if systems:
                hosts = HostinfoFilter(request.GET, queryset=HostRes.objects.filter(systemname__in=systems))
            else:
                msg = 1
                return render(request, 'public/hostsinfo.html', {'msg': msg})
    paginator = Paginator(hosts.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': hosts, }
    return render(request, 'public/hostsinfo.html', context)


@permission_required('public.host_manage', raise_exception=True)
def hostsmod(request):
    """主机修改页面"""
    id = request.GET.get('id')
    hosts = HostsLists.objects.get(id=id)
    user = User.objects.get(username=request.user.username)
    group = user.groups.all().first()
    if user.username == 'root':
        system = SystemsLists.objects.all()
    else:
        system = group.systemslists_set.all()
    obj = HostForm()
    if request.method == 'POST':
        host_form = HostForm(request.POST)
        if host_form.is_valid():
            systemname = request.POST.get('systemname')
            servicename = request.POST.get('servicename')
            clustername = request.POST.get('clustername')
            hostname = request.POST.get('hostname')
            Location = request.POST.get('Location')
            ip = request.POST.get('ip')
            type = request.POST.get('type')
            groups = request.POST.get('groups')
            in4A = request.POST.get('in4A')
            manage = request.POST.get('manage')
            product = request.POST.get('product')
            if ip == hosts.ip:
                hostname_indb = ''
            else:
                hostname_indb = HostsLists.objects.filter(ip=ip)
            if hostname_indb:
                msg = "服务器ip已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                HostsLists.objects.filter(id=request.GET.get('id')).update(
                    systemname=systemname,
                    servicename=servicename,
                    clustername=clustername,
                    hostname=hostname,
                    ip=ip,
                    type=type,
                    groups=groups,
                    location=Location,
                    in4A=in4A,
                    manage=manage,
                    product=product
                )
                return redirect('/ansible/hostslist')
        else:
            errors = host_form.errors
            return render(request, 'public/hostsmod.html',
                          {'obj': host_form, 'hosts': hosts, 'system': system, 'error': errors})
    return render(request, 'public/hostsmod.html', {"obj": obj, 'hosts': hosts,  "system": system})


@permission_required('public.host_manage', raise_exception=True)
def hostsadd(request):
    """主机新增页面"""
    user = User.objects.get(username=request.user.username)
    group = user.groups.all().first()
    if user.username == 'root':
        system = SystemsLists.objects.all()
    else:
        system = group.systemslists_set.all()
    obj = HostForm()
    if request.method == 'POST':
        host_form = HostForm(request.POST)
        if host_form.is_valid():
            systemname = request.POST.get('systemname')
            servicename = request.POST.get('servicename')
            clustername = request.POST.get('clustername')
            hostname = request.POST.get('hostname')
            Location = request.POST.get('Location')
            ip = request.POST.get('ip')
            type = request.POST.get('type')
            groups = request.POST.get('groups')
            in4A = request.POST.get('in4A')
            manage = request.POST.get('manage')
            product = request.POST.get('product')
            hostname_indb = HostsLists.objects.filter(ip=ip)
            if hostname_indb:
                msg = "服务器名字已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                HostsLists.objects.create(
                    systemname=systemname,
                    servicename=servicename,
                    clustername=clustername,
                    in4A=in4A,
                    manage=manage,
                    location=Location,
                    hostname=hostname,
                    ip=ip,
                    type=type,
                    groups=groups,
                    product=product
                )
                return redirect('/ansible/hostslist')
        else:
            errors = host_form.errors
            return render(request, 'public/hostsadd.html', {'obj': host_form, 'system': system, 'error': errors})
    return render(request, 'public/hostsadd.html', {"obj": obj, "system": system})


@permission_required('public.host_manage', raise_exception=True)
def hostsexport(request):
    """导出主机信息"""
    user = User.objects.get(username=request.user.username)
    if user.username == 'root':
        hosts = HostFilter(request.GET, request=request, queryset=HostsLists.objects.all())
    else:
        if user.groups.all().first():
            group = user.groups.all().first()
            system = group.systemslists_set.all()
            systems = list(system.values_list('systemname', flat=True))
            hosts = HostFilter(request.GET, request=request, queryset=HostsLists.objects.filter(systemname__in=systems))
    hosts_resource = HostsResource()
    dataset = hosts_resource.export(hosts.qs)
    response = HttpResponse(dataset.xlsx, content_type='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename="hosts.xlsx"'
    return response


@permission_required('public.host_manage', raise_exception=True)
def hostinfoexport(request):
    """导出主机信息"""
    user = User.objects.get(username=request.user.username)
    if user.username == 'root':
        hostinfo = HostinfoFilter(request.GET, queryset=HostRes.objects.all())
    else:
        if user.groups.all().first():
            group = user.groups.all().first()
            system = group.systemslists_set.all()
            systems = list(system.values_list('systemname', flat=True))
            hostinfo = HostinfoFilter(request.GET, queryset=HostRes.objects.filter(systemname__in=systems))
    hostinfo_resource = HostinfoResource()
    dataset = hostinfo_resource.export(hostinfo.qs)
    response = HttpResponse(dataset.xlsx, content_type='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename="hostinfo.xlsx"'
    return response


@permission_required('public.asset_manage', raise_exception=True)
def assetsexport(request):
    """导出主机信息"""
    assetslist = AssetsFilter(request.GET, queryset=Assets.objects.all())
    hosts_resource = AssetsResource()
    dataset = hosts_resource.export(assetslist.qs)
    response = HttpResponse(dataset.xlsx, content_type='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename="assets.xlsx"'
    return response


@permission_required('public.host_manage', raise_exception=True)
def hostsimportpage(request):
    return render(request, 'public/hostsimport.html')


@permission_required('public.asset_manage', raise_exception=True)
def assetsimportpage(request):
    return render(request, 'public/assetsimport.html')


@permission_required('public.host_manage', raise_exception=True)
def depcalcpage(request):
    return render(request, 'public/depreciation_calc.html')


@permission_required('public.host_manage', raise_exception=True)
def hostsimport(request):
    if request.method == 'POST':
        hosts_resource = HostsResource()
        dataset = Dataset()
        new_hosts = request.FILES['myfile']
        imported_data = dataset.load(new_hosts.read())
        result = hosts_resource.import_data(imported_data, dry_run=True)
        for i in result.row_errors():
            print(i[1][0].error)
        if not result.has_errors():
            hosts_resource.import_data(imported_data, dry_run=False)
        return redirect('/ansible/hostslist')


@permission_required('public.asset_manage', raise_exception=True)
def assetsimport(request):
    if request.method == 'POST':
        assets_resource = AssetsResource()
        dataset = Dataset()
        new_hosts = request.FILES['myfile']
        imported_data = dataset.load(new_hosts.read())
        result = assets_resource.import_data(imported_data, dry_run=True)
        for i in result.row_errors():
            print(i[1][0].error)
        if not result.has_errors():
            assets_resource.import_data(imported_data, dry_run=False)
        return redirect('/ansible/assets')


@permission_required('public.host_manage', raise_exception=True)
def hostsdelete(request):
    """主机删除"""
    HostsLists.objects.filter(id=request.GET.get('id')).delete()
    return redirect('/ansible/hostslist')


@permission_required('public.host_view', raise_exception=True)
def playbooklist(request):
    """系统列表页"""
    playbook = PlaybookFilter(request.GET, queryset=Playbooks.objects.all())
    paginator = Paginator(playbook.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': playbook, }
    return render(request, 'public/playbook.html', context)


def playbookcheck(request, playbook):
    """系统列表页"""
    #print(playbook)
    msg = AnsibleOpt.playbook_check(playbook)
    #print(msg)
    return JsonResponse(msg, safe=False)


@permission_required('public.playbook_manage', raise_exception=True)
def playbookaddpage(request):
    """Playbook新增页面"""
    author = User.objects.get(username=request.user.username)
    playbook = {}
    playbook['author'] = author
    return render(request, 'public/playbooks_detail.html', {"object": playbook, "status": 1 })


@permission_required('public.playbook_manage', raise_exception=True)
def playbookupdate(request):
    """Playbook更新"""
    status = request.POST.get('status')
    pstatus = request.POST.get('pstatus')
    nickName = request.POST.get('nickName')
    playbookname = request.POST.get('playbook')
    remark = request.POST.get('remark')
    playbook_text = request.POST.get('playbook_text')
    playbook = Playbooks.objects.filter(playbook=playbookname)
    if playbook and int(status) == 2:
        with open('ansibleWorker/playbooks/%s' % playbookname, 'w')as f:
            f.writelines(playbook_text)
        playbook = Playbooks.objects.get(playbook=playbookname)
        playbook.nickName = nickName
        playbook.status = pstatus
        playbook.remark = remark
        playbook.save()
        return redirect('/ansible/playbook/%d' % playbook.id)
    if playbook and int(status) == 1:
        msg = "playbook名字已存在，请点击返回重新填写"
        return render(request, 'public/fail.html', {'msg': msg})
    if not playbook and int(status) == 1:
        author = User.objects.get(username=request.user.username)
        playbook = Playbooks.objects.create(
            remark=remark,
            nickName=nickName,
            playbook=playbookname,
            author=author,
            status=pstatus,
        )
        with open('ansibleWorker/playbooks/%s' % playbookname, 'w')as f:
            f.writelines(playbook_text)
        return redirect('/ansible/playbook/%d' % playbook.id)

    return redirect('/ansible/playbooklist')


@permission_required('public.playbook_manage', raise_exception=True)
def playbookdelete(request):
    """Playbook删除"""
    playbook = Playbooks.objects.get(id=request.GET.get('id'))
    os.system('rm -rf ansibleWorker/playbooks/' + playbook.playbook + '')
    playbook.delete()
    return redirect('/ansible/playbooklist')


@permission_required('public.role_manage', raise_exception=True)
def roleaddpage(request):
    """角色新增页面"""
    permission = Permission.objects.exclude(name__startswith='C').order_by()
    systems = SystemsLists.objects.all().order_by()
    return render(request, 'public/roleadd.html', {"permission": permission, 'systems': systems})


@permission_required('public.role_manage', raise_exception=True)
def roleadd(request):
    """角色新增操作"""
    name = request.GET.get('rolename')
    persa = request.GET.get('permission')
    sys = request.GET.get('system')
    if sys.strip() == '':
        system = []
    else:
        system = sys.split(',')
    if persa.strip() == '':
        permission = []
    else:
        permission = persa.split(',')
    groupname_indb = Group.objects.filter(name=name)
    if groupname_indb.exists():
        msg = "角色已存在，请点击返回重新填写"
        return render(request, 'public/fail.html', {'msg': msg})
    else:
        group = Group.objects.create(name=name)
        group.save()
        group = Group.objects.get(name=name)
        if permission:
            for i in permission:
                per = Permission.objects.get(name=i)
                per.group_set.add(group.id)
        else:
            pass
        if system:
            for i in system:
                system_new = SystemsLists.objects.get(systemname=i)
                system_new.group.add(group.id)
        else:
            pass
        return redirect('/ansible/rolelist/1')


@permission_required('public.role_manage', raise_exception=True)
def rolemodpage(request):
    """角色修改页面"""
    ids = request.GET.get('id')
    roles = Group.objects.get(id=ids)
    permission_all = Permission.objects.exclude(name__startswith='C').order_by()
    systems_all = SystemsLists.objects.all().order_by()
    group = Group.objects.get(id=ids)
    per_has_obj = group.permissions.all()
    per_has = []
    pers = {}
    for i in per_has_obj:
        per_has.append(i.name)
    for i in permission_all:
        if i.name in per_has:
            pers[i.name] = True
        else:
            pers[i.name] = False
    sys_has_obj = group.systemslists_set.all()
    sys_has = []
    syss = {}
    for i in sys_has_obj:
        sys_has.append(i.systemname)
    for i in systems_all:
        if i.systemname in sys_has:
            syss[i.systemname] = True
        else:
            syss[i.systemname] = False
    return render(request, 'public/rolemod.html', {'roles': roles, 'pers': pers, 'syss': syss})


@permission_required('public.role_manage', raise_exception=True)
def rolemod(request):
    """角色修改操作"""
    id = request.GET.get('id')
    rolename = request.GET.get('rolename')
    persa = request.GET.get('permission')
    sys = request.GET.get('system')
    group = Group.objects.get(id=id)
    if rolename == group.name:
        groupname_indb = ''
    else:
        groupname_indb = Group.objects.filter(name=group.name)
    if groupname_indb:
        msg = "角色名称已存在，请点击返回重新填写"
        return render(request, 'public/fail.html', {'msg': msg})
    if sys.strip() == '':
        system = []
    else:
        system = sys.split(',')
    if persa.strip() == '':
        permission = []
    else:
        permission = persa.split(',')
    """权限新增"""
    if permission:
        if group.permissions.all().exists():
            pers = group.permissions.all()
            for i in pers:
                per = Permission.objects.get(name=i.name)
                per.group_set.remove(group.id)
            for i in permission:
                per = Permission.objects.get(name=i)
                per.group_set.add(group.id)
        else:
            for i in permission:
                per = Permission.objects.get(name=i)
                per.group_set.add(group.id)
    else:
        if group.permissions.all().exists():
            pers = group.permissions.all()
            for i in pers:
                per = Permission.objects.get(name=i.name)
                per.group_set.remove(group.id)
    """系统新增"""
    if system:
        if group.systemslists_set.all().exists():
            syss = group.systemslists_set.all()
            for i in syss:
                sys = SystemsLists.objects.get(systemname=i.systemname)
                sys.group.remove(group.id)
            for i in system:
                sys = SystemsLists.objects.get(systemname=i)
                sys.group.add(group.id)
        else:
            for i in system:
                sys = SystemsLists.objects.get(systemname=i)
                sys.group.add(group.id)
    else:
        if group.systemslists_set.all().exists():
            syss = group.systemslists_set.all()
            for i in syss:
                sys = SystemsLists.objects.get(systemname=i.systemname)
                sys.group.remove(group.id)
    group.name = rolename
    group.save()
    return redirect('/ansible/rolelist/1')


@permission_required('public.role_manage', raise_exception=True)
def roledelete(request):
    """角色删除"""
    Group.objects.filter(id=request.GET.get('id')).delete()
    return redirect('/ansible/rolelist/1')


@permission_required('public.auth_view', raise_exception=True)
def rolelist(request, number):
    """系统列表页"""
    groups = Group.objects.only('name').exclude(name='root')
    if number is None:
        number = 1
    else:
        number = int(number)
    paginator = Paginator(groups, 10)
    page = paginator.page(number)
    total = paginator.num_pages
    return render(request, 'public/roles.html', {'page': page, 'total': total})


@permission_required('public.user_manage', raise_exception=True)
def useradd(request):
    """用户新增"""
    group = Group.objects.all()
    obj = UserForm()
    time = timezone.now().strftime("%Y%m%d%H%M%S")
    user_id = 'USER' + time
    if request.method == 'POST':
        user_form = UserForm(request.POST)
        if user_form.is_valid():
            username = request.POST.get('username')
            password = request.POST.get('password')
            username_indb = User.objects.filter(username=username)
            if username_indb:
                msg = "用户已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                User.objects.create_user(username=username, password=password, user_id=user_id)
                groupname = request.POST.get('group')
                user = User.objects.get(username=username)
                group_new = Group.objects.get(name=groupname)
                group_new.user_set.add(user.id)
                return redirect('/ansible/userlist/1')
        else:
            errors = user_form.errors
            return render(request, 'public/useradd.html', {'obj': user_form, 'group': group, 'error': errors})
    return render(request, 'public/useradd.html', {"obj": obj, 'group': group})


@permission_required('public.user_manage', raise_exception=True)
def usermod(request):
    """用户修改页面"""
    id = request.GET.get('id')
    user = User.objects.get(id=id)
    group = Group.objects.get(name=(user.groups.all().first()).name)
    group_all = Group.objects.all()
    status = user.is_active
    status_all = ['True', 'False']
    obj = UserModForm()
    if request.method == 'POST':
        user_form = UserModForm(request.POST)
        if user_form.is_valid():
            username = request.POST.get('username')
            status = request.POST.get('status')
            groupname = request.POST.get('group')
            if username == user.username:
                username_indb = ''
            else:
                username_indb = User.objects.filter(username=username)

            if username_indb:
                msg = "用户名称已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            group_new = Group.objects.get(name=groupname)
            if user.groups.all().first() is not None:
                group_old = Group.objects.get(name=(user.groups.all().first()).name)
                group_old.user_set.remove(user.id)
            group_new.user_set.add(user.id)
            user.username = username
            user.is_active = status
            user.save()
            return redirect('/ansible/userlist/1')
        else:
            errors = user_form.errors
            return render(request, 'public/usermod.html',
                          {'obj': user_form, 'status': status, 'status_all': status_all, 'user': user, 'group': group,
                           'group_all': group_all, 'error': errors})
    return render(request, 'public/usermod.html',
                  {"obj": obj, 'status': status, 'status_all': status_all, 'user': user, 'group_all': group_all,
                   'group': group})


@permission_required('public.user_manage', raise_exception=True)
def userdelete(request):
    """用户删除"""
    User.objects.filter(id=request.GET.get('id')).delete()
    return redirect('/ansible/userlist/1')


@permission_required('public.user_manage', raise_exception=True)
def userreset(request):
    """用户重置密码"""
    user = User.objects.get(id=request.GET.get('id'))
    user.set_password('Ki0c@2024')
    user.save()
    return redirect('/ansible/userlist/1')


@login_required()
def userchangepwd(request):
    """用户重置密码"""
    obj = PwdModForm()
    if request.method == 'POST':
        pwdch_form = PwdModForm(request.POST)
        if pwdch_form.is_valid():
            pwd_old = request.POST.get('pwd_old')
            pwd_new = request.POST.get('pwd_new')
            pwd_new_confirm = request.POST.get('pwd_new_confirm')
            if pwd_new != pwd_new_confirm:
                msg1 = '两次新密码不一致，请重新输入'
                return render(request, 'public/userchangepwd.html',
                              {'obj': pwdch_form, 'msg1': msg1})
            else:
                user = request.user
                if check_password(pwd_old, user.password):
                    user.set_password(pwd_new)
                    user.save()
                    update_session_auth_hash(request, user)
                    return redirect('/homepage/')
                else:
                    msg2 = '原密码输入错误'
                    return render(request, 'public/userchangepwd.html',
                                  {'obj': pwdch_form, 'msg2': msg2})
        else:
            errors = pwdch_form.errors
            return render(request, 'public/userchangepwd.html',
                          {'obj': pwdch_form, 'error': errors})
    return render(request, 'public/userchangepwd.html', {"obj": obj})


@permission_required('public.auth_view', raise_exception=True)
def userlist(request, number):
    """用户列表页"""
    users = User.objects.all().exclude(username='root')
    if number is None:
        number = 1
    else:
        number = int(number)
    paginator = Paginator(users, 10)
    page = paginator.page(number)
    total = paginator.num_pages
    return render(request, 'public/users.html', {'page': page, 'total': total})


class PlaybookDetail(LoginRequiredMixin, DetailView):
    """playbook 详情页"""
    model = Playbooks
    login_url = '/account/login'
    redirect_field_name = 'redirect_to'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        pb = context['object'].playbook
        with open('ansibleWorker/playbooks/%s' % pb)as f:
            s = f.read()
        context['yml_content'] = s
        context['status'] = 0
        return context


@permission_required('public.host_view', raise_exception=True)
def softwarelist(request):
    """软件列表页"""
    sw = Softwares.objects.all()
    for i in sw:
        file_path = os.path.join(BASE_DIR, 'ansibleWorker/software/', i.software)
        a = os.path.exists(file_path)
        if a:
            Softwares.objects.filter(software=i).update(
                status="软件包存在"
            )
        else:
            Softwares.objects.filter(software=i).update(
                status="软件包不存在"
            )
    software = SoftwareFilter(request.GET, queryset=Softwares.objects.all())
    paginator = Paginator(software.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': software, }
    return render(request, 'public/software.html', context)


@permission_required('public.software_manage', raise_exception=True)
def softwareaddpage(request):
    obj = SoftwareForm()
    if request.method == 'POST':
        software_form = SoftwareForm(request.POST)
        if software_form.is_valid():
            software = request.POST.get('software')
            remark = request.POST.get('remark')
            softwarefile = request.FILES.get('softwarefile')
            base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
            f = open(os.path.join(base_dir, 'ansibleWorker', 'software', software), 'wb')
            for chunk in softwarefile.chunks():
                f.write(chunk)
            f.close()
            author = User.objects.get(username=request.user.username)
            status = "新建"
            Softwares.objects.create(
                software=software,
                status=status,
                author=author
            )
            return redirect('/ansible/softwarelist')
        else:
            errors = software_form.errors
            return render(request, 'public/softwareadd.html', {'obj': software_form, 'error': errors})
    return render(request, 'public/softwareadd.html', {"obj": obj, })


@permission_required('public.playbook_manage', raise_exception=True)
def softwareadd(request):
    """software新增操作"""
    remark = request.POST.get('remark')
    software = request.POST.get('software')
    softwarefile = request.FILES.get('softwarefile', None)
    softwarefile_dir = request.FILES.getlist('softwarefile_dir', None)
    if softwarefile and softwarefile_dir:
        msg = "不能同时上传单个文件和文件夹，请点击返回重新选择"
        return render(request, 'public/fail.html', {'msg': msg})
    software_indb = Softwares.objects.filter(software=software)
    if software_indb:
        msg = "software名字已存在，请点击返回重新填写"
        return render(request, 'public/fail.html', {'msg': msg})
    if softwarefile:
        f = open(os.path.join(BASE_DIR, 'ansibleWorker/software', software), 'wb')
        for chunk in softwarefile.chunks():
            f.write(chunk)
        f.close()
    else:
        software_path = os.path.join(BASE_DIR, 'ansibleWorker/software/', software)
        os.mkdir(software_path)
        for i in softwarefile_dir:
            f = open(os.path.join(BASE_DIR, 'ansibleWorker/software/%s' % software, str(i)), 'wb')
            for chunk in i.chunks():
                f.write(chunk)
            f.close()
    author = User.objects.get(username=request.user.username)
    status = "新建"
    Softwares.objects.create(
        remark=remark,
        software=software,
        author=author,
        status=status,
    )
    return redirect('/ansible/softwarelist')


@permission_required('public.software_manage', raise_exception=True)
def softwaremodpage(request):
    """software修改页面"""
    id = request.GET.get('id')
    software = Softwares.objects.get(id=id)
    return render(request, 'public/softwaremod.html', {'software': software})


@permission_required('public.software_manage', raise_exception=True)
def softwaremod(request):
    """software修改操作"""
    softwarename = request.POST.get('software')
    remark = request.POST.get('remark')
    software = Softwares.objects.get(id=request.GET.get('id'))
    if softwarename == software.software:
        software_indb = ''
    else:
        software_indb = Softwares.objects.filter(software=softwarename)
    if software_indb:
        msg = "software名字已存在，请点击返回重新填写"
        return render(request, 'public/fail.html', {'msg': msg})
    else:
        software_oldname = os.path.join(BASE_DIR, 'ansibleWorker/software/', software.software)
        software_newname = os.path.join(BASE_DIR, 'ansibleWorker/software/', softwarename)
        os.system('mv '+software_oldname+' '+software_newname+'')
        software.software = softwarename
        software.remark = remark
        software.save()
        return redirect('/ansible/softwarelist')


@permission_required('public.software_manage', raise_exception=True)
def softwaredelete(request):
    """software删除"""
    software = Softwares.objects.get(id=request.GET.get('id'))
    software_path = os.path.join(BASE_DIR, 'ansibleWorker/software/', software.software)
    if os.path.exists(software_path):
        if os.path.isfile(software_path):
            os.remove(software_path)
        elif os.path.isdir(software_path):
            for root, dirs, files in os.walk(software_path, topdown=False):
                for name in files:
                    os.remove(os.path.join(root, name))
                for name in dirs:
                    os.removedirs(os.path.join(root, name))
            os.removedirs(software_path)
    Softwares.objects.filter(id=request.GET.get('id')).delete()
    return redirect('/ansible/softwarelist')


@permission_required('public.software_manage', raise_exception=True)
def transpackage(request):
    """分发包页面"""
    user = User.objects.get(username=request.user.username)
    if user.username == 'root':
        system = SystemsLists.objects.all()
    else:
        if user.groups.all().first():
            group = user.groups.all().first()
            system = group.systemslists_set.all()
    syslist = list(set(system.values_list('systemname', flat=True)))
    softwares = Softwares.objects.all()
    roles = AnsibleRole.objects.filter(status='roles存在')
    return render(request, 'public/dispatch.html', {'syslist': syslist, 'roles': roles, 'softwares': softwares})


@permission_required('public.ansible_trans', raise_exception=True)
def dispatch(request):
    """分发软件"""
    print("dispatch begin!!!")
    rolelist = request.GET.get('roles')
    softlist = request.GET.get('softs')
    syslist = request.GET.get('syss')
    software = ast.literal_eval(softlist) if softlist else []
    roles = ast.literal_eval(rolelist) if rolelist else []
    system = ast.literal_eval(syslist) if syslist else []
    print("system: %s" % system)
    if len(software) == 0 and len(roles) == 0:
        msg = "至少选择一个软件或者角色，请点击返回重新填写"
        print(msg)
        return render(request, 'public/fail.html', {'msg': msg})
    if len(system) == 0:
        msg = "没有选择系统，请点击返回重新填写"
        return render(request, 'public/fail.html', {'msg': msg})
    results = []
    for i in system:
        print("here: %s" % i)
        sys = SystemsLists.objects.get(systemname=i)
        sys_ip = sys.control_host
        sys_user = sys.agent_user
        print(sys_user)
        sys_pass = str(des_decrypt(DES_SECRET_KEY, sys.agent_pass), 'utf-8')
        for j in software:
            result = AnsibleOpt.software_trans(j, sys_ip, sys_user, sys_pass)
            if result == 0:
                results.append("软件包" + j + "发送到系统" + i + "成功")
            else:
                results.append("软件包" + j + "发送到系统" + i + "失败")
        for k in roles:
            result = AnsibleOpt.ansible_roles_trans(k, sys_ip, sys_user, sys_pass)
            if result == 0:
                results.append("角色" + k + "发送到系统" + i + "成功")
            else:
                results.append("角色" + k + "发送到系统" + i + "失败")
    AnsibleRoleTasks.objects.create(
        msg=results,
        ansiblerole=software+roles,
        system=system,
    )
    msg = results
    return JsonResponse(msg, safe=False)


@permission_required('public.host_view', raise_exception=True)
def ansiblerolelist(request):
    """ansiblerole列表页"""
    roles = AnsibleRole.objects.all()
    for i in roles:
        file_path = os.path.join(BASE_DIR, 'ansibleWorker/playbooks/roles', i.ansiblerole)
        a = os.path.exists(file_path)
        if a:
            AnsibleRole.objects.filter(ansiblerole=i).update(
                status="roles存在"
            )
        else:
            AnsibleRole.objects.filter(ansiblerole=i).update(
                status="roles不存在"
            )
    ansiblerole = AnsibleRoleFilter(request.GET, queryset=AnsibleRole.objects.all())
    paginator = Paginator(ansiblerole.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': ansiblerole, }
    return render(request, 'public/ansiblerole.html', context)


@permission_required('public.ansiblerole_manage', raise_exception=True)
def ansibleroleadd(request):
    """ansiblerole新增页面"""
    obj = AnsibleRoleForm()
    if request.method == 'POST':
        ansiblerole_form = AnsibleRoleForm(request.POST)
        if ansiblerole_form.is_valid():
            ansiblerole = request.POST.get('ansiblerole')
            remark = request.POST.get('remark')
            ansiblerole_indb = AnsibleRole.objects.filter(ansiblerole=ansiblerole)
            if ansiblerole_indb:
                msg = "ansiblerole已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                AnsibleRole.objects.create(
                    ansiblerole=ansiblerole,
                    remark=remark,
                )
                return redirect('/ansible/ansiblerolelist')
        else:
            errors = ansiblerole_form.errors
            return render(request, 'public/ansibleroleadd.html', {'obj': ansiblerole_form, 'error': errors})
    return render(request, 'public/ansibleroleadd.html', {"obj": obj, })


@permission_required('public.ansiblerole_manage', raise_exception=True)
def ansibleroledownload(request):
    """ansiblerole新增页面"""
    ansiblerole = request.GET.get('ansiblerole')
    """下载roles"""
    msg = AnsibleOpt.ansible_roles(ansiblerole=ansiblerole)
    AnsibleRole.objects.filter(ansiblerole=ansiblerole).update(
        download_status=msg
    )
    AnsibleRoleTasks.objects.create(
        ansiblerole=ansiblerole,
        msg=msg
    )
    print("ansiblerole下载任务已创建")


@permission_required('public.ansible_trans_views', raise_exception=True)
def ansibleroledownloadtasks(request):
    """ansiblerole下载页面"""
    ansibleroletasks = AnsibleRoleTasksFilter(request.GET, queryset=AnsibleRoleTasks.objects.all())
    paginator = Paginator(ansibleroletasks.qs, 10)
    page = request.GET.get('page')
    page_obj = paginator.get_page(page)
    total = paginator.num_pages
    context = {'page_obj': page_obj, 'total': total, 'paginator': paginator,
               'is_paginated': True, 'filter': ansibleroletasks, }
    return render(request, 'public/ansibleroletasks.html', context)


@permission_required('public.ansiblerole_manage', raise_exception=True)
def ansiblerolemod(request):
    """ansiblerole修改页面"""
    id = request.GET.get('id')
    ansibleroles = AnsibleRole.objects.get(id=id)
    obj = AnsibleRoleForm()
    if request.method == 'POST':
        ansiblerole_form = AnsibleRoleForm(request.POST)
        if ansiblerole_form.is_valid():
            ansiblerole = request.POST.get('ansiblerole')
            remark = request.POST.get('remark')
            if ansiblerole == ansibleroles.ansiblerole:
                ansiblerole_indb = ''
            else:
                ansiblerole_indb = AnsibleRole.objects.filter(ansiblerole=ansiblerole)
            if ansiblerole_indb:
                msg = "ansiblerole已存在，请点击返回重新填写"
                return render(request, 'public/fail.html', {'msg': msg})
            else:
                ansiblerole_oldname = os.path.join(BASE_DIR, 'ansibleWorker/playbooks/roles/', AnsibleRole.objects.get(id=request.GET.get('id')).ansiblerole)
                ansiblerole_newname = os.path.join(BASE_DIR, 'ansibleWorker/playbooks/roles/', ansiblerole)
                os.system('mv ' + ansiblerole_oldname + ' ' + ansiblerole_newname + '')
                AnsibleRole.objects.filter(id=request.GET.get('id')).update(
                    ansiblerole=ansiblerole,
                    remark=remark,
                )
                return redirect('/ansible/ansiblerolelist')
        else:
            errors = ansiblerole_form.errors
            return render(request, 'public/ansiblerolemod.html', {'obj': ansiblerole_form, 'error': errors})
    return render(request, 'public/ansiblerolemod.html', {"obj": obj, "ansibleroles": ansibleroles})


@permission_required('public.ansiblerole_manage', raise_exception=True)
def ansibleroledelete(request):
    """系统删除"""
    ansibleroles = AnsibleRole.objects.get(id=request.GET.get('id'))
    os.system('rm -rf ansibleWorker/playbooks/roles/' + ansibleroles.ansiblerole + '')
    ansibleroles.delete()
    return redirect('/ansible/ansiblerolelist')


@permission_required('public.middle_monitor_view', raise_exception=True)
def middlemonitor(request):
    """中间件监控"""
    return redirect(MONITOR_URL+'targets')


def mydashboard(request):
    hostcnt = HostsLists.objects.count()
    systemcnt = SystemsLists.objects.count()
    taskcnt = AnsibleTasks.objects.count()
    usercnt = User.objects.count()
    return render(request, 'public/mydashboard.html',{'hostcount': hostcnt, 'systemcount': systemcnt, 'taskcount': taskcnt, 'usercount': usercnt})


def getplaybook(request):
    """执行playbook时，查看选中的playbook"""
    if request.method == "GET":
        playbook = request.GET.get('playbook')
        with open(os.path.join(BASE_DIR, 'ansibleWorker/playbooks', playbook), 'r')as f:
            pb = f.read()
        if pb:
            return JsonResponse(pb, safe=False)


def depcalc(request):
    """执行playbook时，查看选中的playbook"""
    if request.method == "POST":
        assetlabels = request.POST.get('assetlabels')
        monthline = request.POST.get('monthline')
        month = int(monthline)
        #print(month)
        assetlblist = assetlabels.strip().split(',')
        assetslist = Assets.objects.filter(label__in=assetlblist)
        #print(assetslist)
        resultf = sum([i.depallowance_term*i.remainmonth+i.depallowance_year if i.remainmonth < month else i.depallowance_term*month+i.depallowance_year for i in assetslist ])
        result = round(resultf,2)
        return JsonResponse(result, safe=False)


def login4Ain(request):
    token = request.GET.get('token')
    appAcctId = request.GET.get('appAcctId')
    flag = request.GET.get('flag')
    time = timezone.now().strftime("%Y%m%d%H%M%S")
   # url = "http://192.168.15.100:8081/uac/services/CheckAiuapTokenSoap?wsdl"
    client = Client(url)
    result = client.service.CheckAiuapTokenSoap(
        "<?xml version='1.0' encoding='UTF-8'?><USERRSP><HEAD><CODE></CODE><SID></SID>"
        "<TIMESTAMP>" + time + "</TIMESTAMP>"
                               "<SERVICEID>CQNGOneCup</SERVICEID></HEAD><BODY>"
                               "<APPACCTID>" + appAcctId + "</APPACCTID>"
                                                           "<TOKEN>" + token + "</TOKEN></BODY></USERRSP>")
    print(result['_value_1'])
    rsp = re.findall(r'<RSP>(.*)</RSP>', result['_value_1'])
    appacctid = re.findall(r'<APPACCTID>(.*)</APPACCTID>', result['_value_1'])
    print(rsp)
    if int(rsp[0]) == 0:
        user = User.objects.filter(username=appacctid[0])
        if user.exists():
            user = User.objects.get(username=appacctid[0])
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/homepage/')
    return HttpResponseRedirect('/account/login')


def runtask(request, sys):
    user = User.objects.get(username=request.user.username)
    if user.username == 'root':
        system = SystemsLists.objects.all()
    else:
        if user.groups.all().first():
            group = user.groups.all().first()
            system = group.systemslists_set.all()
    systems = list(set(system.values_list('systemname', flat=True)))
    playbooks = Playbooks.objects.all()
    selectedpb = request.GET.get('sldpb')
    if sys == 1:
        system = ''
        hosttree = []
    else:
        system = request.GET.get('systems')
        hostlist = HostsLists.objects.filter(systemname=system, manage=True)
        hosttree = gethosttree(hostlist)
    return render(request, 'public/ansibletask_run.html',
                  {'systems': systems, 'hosttree': json.dumps(hosttree), 'playbooks': playbooks, 'system': system, 'sldpb': selectedpb})


def gethosttree(hostlist):
    htree = tree()
    for host in hostlist:
        naip = host.hostname + '__' + host.ip
        htree[host.systemname]['L_'+host.location]['S_'+host.servicename][naip] = 1
    hosttree = dict(htree)
    return dicttolist(hosttree)


def tree():
    return defaultdict(tree)


def dicttolist(hdict):
    if isinstance(hdict, dict):
        menudict = {}
        hlist = []
        for hkey in hdict:
            menudict['text'] = hkey
            if isinstance(hdict[hkey], dict):
                menudict['nodes'] = dicttolist(hdict[hkey])
            hlist.append(menudict)
            menudict = {}
    return hlist


def sendtask(request):
    #print("send task view")
    user = request.user
    data = []
    var = request.POST.get('vars')
    try:
        var = var.strip('\"')
        extra_vars = ast.literal_eval(var) if var else {}
    except Exception as e:
        print(e)
    systemname = request.POST.get('systemname')
    #print(extra_vars)
    playbook = request.POST.get('playbook')
    system = SystemsLists.objects.get(systemname=systemname)
    remote_user = system.ssh_user
    remote_pass = str(des_decrypt(DES_SECRET_KEY, system.ssh_pass), 'utf-8')
    become_user = request.POST.get('become_user')
    become_pass = request.POST.get('become_pass')
    try:
        removed_value = extra_vars.pop('demo', "没有demo")
    except Exception as er:
        print(er)
    hostlist = request.POST.get('hostlist')
    become = {}
    if become_user:
        become['user'] = become_user
        become['pass'] = become_pass
    for host in ast.literal_eval(hostlist):
        groups = HostsLists.objects.get(systemname=systemname, ip=host).groups
        data.append({
            'ip': host,
            'groups': groups,
            'username': remote_user,
            'password': remote_pass,
            'become': become,
        })
    s = AnsibleOpt.ansible_playbook(
        systemname=systemname,
        playbook=playbook,
        inventory=data,
        user=user,
        extra_vars=extra_vars,
        **{'label': request.META.get('REMOTE_ADDR')}
    )
    b = s.get('id')
    return JsonResponse(b, safe=False)


